/*
 * @Author: xiaosihan
 * @Date: 2023-08-05 23:39:54
 * @Last Modified by: xiehangyun
 * @Last Modified time: 2025-02-27 19:01:19
 */
import { DesignData, GoodsData, NameNum, NameNumSide, RepeatType } from '#/type';
import userDesignService from '@/api/services/userDesignService';
import utilsServer from '@/api/services/utilsServer';
import { cloneDeep, debounce, first, get, set } from 'lodash';
import { configure, observable, toJS } from 'mobx';
import designDataHistory from './designDataHistory';
import preview2DRenderer from './preview2DRenderer';
import thumb3DRenderer from './thumb3DRenderer';
import FabricText from '@/myFabric/FabricText';
import designEditor from './designEditor';
import textureManager from './textureManager';
import fontManage from '@/myFabric/fontManage';

configure({ enforceActions: 'never' });

const editorStore = (window.editorStore = observable(
  {
    // 加载中
    loadding: false,
    setLoadding(loadding: boolean) {
      this.loadding = loadding;
    },

    // 是否有更新
    needUpdateTime: 0,
    updataTime() {
      this.needUpdateTime++;
    },

    // 模版数据
    design_data: {
      color: '白色',
      colorValue: '#ffffff',
      designData: {},
      ppId: 0,
      previewThumb: [],
      thumbs: [],
      printArea: 'front', // (front,back,double)
      threadColor: '#ffffff', //缝线的颜色
    } as DesignData,
    setDesignData(design_data: DesignData) {
      this.design_data = design_data;
    },
    setThreadColor(color: `#${string}`) {
      this.design_data.threadColor = color;
      this.updataTime();
    },
    // 修改设计数据
    modifyDesignData(designData: DesignData['designData'], name?: string) {
      this.updataTime();
      if (this.design_data && (name || this.activeComponent)) {
        set(this, ['design_data', 'designData', name || this.activeComponent], designData);
      }
    },

    // 修改缩略图
    modifyThumb(thumb: string = '', back_thumb: string = '') {
      this.design_data.thumbs = [thumb, back_thumb];
    },

    // 商品数据
    goodsData: undefined as GoodsData | undefined,
    setGoodsData(goodsData: GoodsData) {
      this.updataTime();
      this.goodsData = goodsData;
      const activeComponent = get(goodsData, ['component', 0, 'key']);
      this.setActiveComponent(activeComponent);

      // //初始名字加号码的参数  这里的代码 影响到了切换产品时默认选中第一个裁片的逻辑了
      // const goodsSides = goodsData.component.map((c) => c.key);
      // //需要支持的面
      // const allSide: Array<NameNumSide> = [
      //   'front',
      //   'back',
      //   'left_front',
      //   'right_front',
      //   'left_back',
      //   'right_back',
      // ];
      // const initSide = first(allSide.filter((s) => goodsSides.includes(s)));
      // if (initSide) {
      //   editorStore.setAddName(editorStore.addName, initSide);
      //   editorStore.setAddNum(editorStore.addNum, initSide);
      // }
    },
    clearGoodsData() {
      this.goodsData = undefined;
    },

    //判断是否有这个部位
    hasComponent(component: string) {
      if (this.goodsData) {
        const keys = this.goodsData.component.map((c) => c.key);
        if (keys.includes(component)) {
          return true;
        }
      }
      return false;
    },

    // 当前选中的部位
    activeComponent: '',
    setActiveComponent(activeComponent: string) {
      if (this.goodsData) {
        if (this.hasComponent(activeComponent) && this.activeComponent !== activeComponent) {
          this.activeComponent = activeComponent;
        }
      }
    },

    //保存中
    saveIng: false,
    setSaveIng(saveIng: boolean) {
      this.saveIng = saveIng;
    },

    //图层的ids
    layerIds: '' as string,
    setLayerIds: debounce((layerIds: string) => {
      editorStore.layerIds = layerIds;
    }, 50),

    // 编辑器的缩放
    scale: 200,
    setScale(scale: number) {
      this.scale = scale;
    },

    //设置商品颜色
    setDesignColor(color: string, colorValue: `#${string}`) {
      if (this.activeComponent) {
        this.design_data.designData[this.activeComponent].background = colorValue;
        this.design_data.color = color;
        this.design_data.colorValue = colorValue;
        this.updataTime();
      }
    },

    //最大缩放
    maxScale: 50,
    setMaxScale(maxScale: number) {
      const s = maxScale / this.maxScale;
      this.maxScale = Math.floor(maxScale);
      this.scale = Math.min(this.scale * s, maxScale);
    },

    //当前选中对象的id
    activeObjectId: '',
    setActiveObjectId(activeObjectId: string) {
      this.activeObjectId = activeObjectId;
    },

    // 对象旋转状态
    rotation: 0,
    setRotation(rotation: number) {
      this.rotation = rotation;
    },

    //对象的平铺类型
    repeat: 'no_repeat' as RepeatType,
    setRepeat(repeat: RepeatType = 'no_repeat') {
      this.repeat = repeat;
    },

    // 显示重复间距控制器
    showRepeatSpaceContorl: false,
    setShowRepeatSpaceContorl(showRepeatSpaceContorl: boolean) {
      this.showRepeatSpaceContorl = showRepeatSpaceContorl;
    },

    // 间距关联
    repeatSpacelink: true,
    setRepeatSpacelink(repeatSpacelink: boolean) {
      this.repeatSpacelink = repeatSpacelink;
      if (this.repeatSpacelink) {
        this.repeatSpaceY = this.repeatSpaceX;
      }
    },

    // 平铺的横向间距
    repeatSpaceX: 0,
    setRepeatSpaceX(repeatSpaceX: number = 0) {
      this.repeatSpaceX = repeatSpaceX;
    },

    // 平铺的纵向间距
    repeatSpaceY: 0,
    setRepeatSpaceY(repeatSpaceY: number = 0) {
      this.repeatSpaceY = repeatSpaceY;
    },

    // 图片的遮罩用的svg地址
    clipSvgUrl: '',
    setClipSvgUrl(clipSvgUrl: string = '') {
      this.clipSvgUrl = clipSvgUrl;
    },

    // 设置当前选中文字的字体
    fontFamily: '',
    setFontFamily(fontFamily: string = '') {
      this.fontFamily = fontFamily;
    },

    // 设置当前选中文字的大小
    fontSize: 20,
    setFontSize(fontSize: number) {
      this.fontSize = fontSize;
    },

    // 设置字体间距
    fontSpace: 0,
    setFontSpace(fontSpace: number) {
      this.fontSpace = fontSpace;
    },

    //设置文字弯曲
    bendDegree: 0,
    setBendDegree(bendDegree: number) {
      this.bendDegree = bendDegree;
    },

    // 设置字体行高
    lineHeight: 0,
    setLineHeight(lineHeight: number) {
      this.lineHeight = lineHeight;
    },

    //设置锁定状态
    lock: false,
    setLock(lock: boolean) {
      this.lock = lock;
    },

    //颜色拾取中
    colorPicker: false,
    originColor: '#ffffff',
    pickerColor: '#ffffff', // 吸色工具拾取到的颜色
    setColorPicker(colorPicker: boolean) {
      const { activeComponent, design_data } = editorStore;
      if (colorPicker) {
        this.originColor =
          get(design_data, ['designData', activeComponent, 'background']) || '#ffffff';
      }
      this.colorPicker = colorPicker;
    },
    setPickerColor(color: string) {
      this.pickerColor = color;
    },

    //ai的剩余使用次数
    aiUseCount: 0,
    async updateAiUseCount(type: "kouTu" | "dongMa" | "tuYa" | "xuanRan" = "kouTu") {
      const res = await userDesignService.queryUseCountResult(type);
      return res;
    },

    //涂鸦模式
    graffiti: false,
    setGraffiti(graffiti: boolean) {
      this.graffiti = graffiti;
    },

    //------------------------名字加号码相关的状态
    //名字的字体
    nameFontFamily: fontManage.fontlist[0].id,
    setNameFontFamily(nameFontFamily: string) {
      this.nameFontFamily = nameFontFamily;
      fontManage.loadFont([nameFontFamily]);
      const nameObject = designEditor.fabricCanvas._objects.find((o) => o.name === 'name');
      if (nameObject) {
        this.setFontFamily(nameFontFamily);
        (nameObject as FabricText).set({ fontFamily: nameFontFamily });
        designEditor.render();
      }
    },

    //名字的颜色
    nameColor: '#000000',
    setNameColor(nameColor: string) {
      this.nameColor = nameColor;
      const nameObject = designEditor.fabricCanvas._objects.find(
        (o) => o.name === 'name',
      ) as FabricText;
      if (nameObject) {
        if (this.activeObjectId === nameObject.id) {
          this.setPickerColor(nameColor);
        }
        (nameObject as FabricText).set({ fill: nameColor });
        designEditor.render();
      }
    },
    //添加名字
    addName: false,
    //名字的正反面
    nameSide: 'front' as NameNumSide,
    async setAddName(addName: boolean, nameSide: NameNumSide) {
      this.addName = addName;
      this.nameSide = nameSide;
      this.setActiveComponent(nameSide);
      await new Promise((resolve) => setTimeout(resolve, 100));

      for (let side of ['front', 'back', 'left_front', 'right_front', 'left_back', 'right_back']) {
        const needAddName = addName && side === this.nameSide;
        const needRemoveName = !addName || side !== this.nameSide;

        // 需要添加的操作
        if (needAddName) {
          if (
            side === this.activeComponent &&
            !designEditor.fabricCanvas._objects.some((o) => o.name === 'name')
          ) {
            const nameObject = designEditor.addText('名字', {
              name: 'name',
              fontSize: 200,
              left: 512,
              top: 450,
              fontFamily: this.nameFontFamily,
              fill: this.nameColor,
            });
            nameObject.editable = false;
          } else if (
            side !== this.activeComponent &&
            this.design_data.designData[side] &&
            !this.design_data.designData[side].objects.some((o: any) => o.name === 'name')
          ) {
            const fabricData = this.design_data.designData[side];
            if (fabricData) {
              const nameObject = new FabricText('名字', {
                name: 'name',
                fontSize: 200,
                left: 512,
                top: 450,
                fontFamily: this.nameFontFamily,
                fill: this.nameColor,
              });
              nameObject.editable = false;
              fabricData.objects.push(nameObject.toJSON());
              await textureManager.updataTextByFabricJSON(side, fabricData);
              this.updataTime();
            }
          }
        }

        //需要删除的操作
        if (needRemoveName) {
          if (
            side === this.activeComponent &&
            designEditor.fabricCanvas._objects.some((o) => o.name === 'name')
          ) {
            const nameObject = designEditor.fabricCanvas._objects.find((o) => o.name === 'name');
            if (nameObject) {
              designEditor.fabricCanvas.remove(nameObject);
            }
          } else if (
            side !== this.activeComponent &&
            this.design_data.designData[side] &&
            this.design_data.designData[side].objects.some((o: any) => o.name === 'name')
          ) {
            const fabricData = this.design_data.designData[side];
            if (fabricData) {
              fabricData.objects = fabricData.objects.filter((o: any) => o.name !== 'name');
              await textureManager.updataTextByFabricJSON(side, fabricData);
              this.updataTime();
            }
          }
        }
      }
    },

    //号码的字体
    numFontFamily: fontManage.fontlist[0].id,
    setNumFontFamily(numFontFamily: string) {
      this.numFontFamily = numFontFamily;
      fontManage.loadFont([numFontFamily]);
      const nameObject = designEditor.fabricCanvas._objects.find((o) => o.name === 'num');
      if (nameObject) {
        this.setFontFamily(numFontFamily);
        (nameObject as FabricText).set({ fontFamily: numFontFamily });
        designEditor.render();
      }
    },

    //号码的颜色
    numColor: '#000000',
    setNumColor(numColor: string) {
      this.numColor = numColor;
      const numObject = designEditor.fabricCanvas._objects.find(
        (o) => o.name === 'num',
      ) as FabricText;
      if (numObject) {
        if (this.activeObjectId === numObject.id) {
          this.setPickerColor(numColor);
        }
        (numObject as FabricText).set({ fill: numColor });
        designEditor.render();
      }
    },
    //添加号码
    addNum: false,
    numSide: 'front' as NameNumSide, //号码的正反面
    async setAddNum(addNum: boolean, numSide: NameNumSide) {
      this.addNum = addNum;
      this.numSide = numSide;
      this.setActiveComponent(numSide);
      await new Promise((resolve) => requestAnimationFrame(resolve));
      for (let side of ['front', 'back', 'left_front', 'right_front', 'left_back', 'right_back']) {
        const needAddNum = addNum && side === this.numSide;
        const needRemoveNum = !addNum || side !== this.numSide;

        // 需要添加的操作
        if (needAddNum) {
          if (
            side === this.activeComponent &&
            !designEditor.fabricCanvas._objects.some((o) => o.name === 'num')
          ) {
            const numObject = designEditor.addText('00', {
              name: 'num',
              fontSize: 200,
              left: 512,
              top: 450,
              fontFamily: this.numFontFamily,
              fill: this.numColor,
            });
            numObject.editable = false;
          } else if (
            side !== this.activeComponent &&
            this.design_data.designData[side] &&
            !this.design_data.designData[side].objects.some((o: any) => o.name === 'num')
          ) {
            const fabricData = this.design_data.designData[side];
            if (fabricData) {
              const numObject = new FabricText('00', {
                name: 'num',
                fontSize: 200,
                left: 512,
                top: 450,
                fontFamily: this.numFontFamily,
                fill: this.numColor,
              });
              numObject.editable = false;
              fabricData.objects.push(numObject.toJSON());
              await textureManager.updataTextByFabricJSON(side, fabricData);
              this.updataTime();
            }
          }
        }

        //需要删除的操作
        if (needRemoveNum) {
          if (
            side === this.activeComponent &&
            designEditor.fabricCanvas._objects.some((o) => o.name === 'num')
          ) {
            const numObject = designEditor.fabricCanvas._objects.find((o) => o.name === 'num');
            if (numObject) {
              designEditor.fabricCanvas.remove(numObject);
            }
          } else if (
            side !== this.activeComponent &&
            this.design_data.designData[side] &&
            this.design_data.designData[side].objects.some((o: any) => o.name === 'num')
          ) {
            const fabricData = this.design_data.designData[side];
            if (fabricData) {
              fabricData.objects = fabricData.objects.filter((o: any) => o.name !== 'num');
              await textureManager.updataTextByFabricJSON(side, fabricData);
              this.updataTime();
            }
          }
        }
      }
    },

    //预览名字和号码
    async perViewNameNum(i: number, nameOrNum: 'name' | 'num') {
      const nameNum = this.nameNumList[i];
      if (nameNum) {
        if (nameOrNum === 'name') {
          this.setActiveComponent(this.nameSide);
        } else if (nameOrNum === 'num') {
          this.setActiveComponent(this.numSide);
        }
        await new Promise((resolve) => setTimeout(resolve, 100));
        designEditor.fabricCanvas._objects.map((o) => {
          if (['name', 'num'].includes((o as FabricText).name)) {
            const text = new FabricText();
            text.set(o as Partial<FabricText>);

            if (o.name === 'name') {
              (text as FabricText).set({ text: nameNum.name });
            } else if (o.name === 'num') {
              (text as FabricText).set({ text: String(nameNum.num) });
            }

            const w = text.getScaledWidth();
            const h = text.getScaledHeight();
            const scale = Math.min(
              (o as FabricText).originWidth / w,
              (o as FabricText).originHeight / h,
            );

            (o as FabricText).fontSize! *= scale;

            //如果是当前选中的对象就同步一下字体大小的参数
            if ((o as FabricText).id === this.activeObjectId) {
              this.setFontSize((o as FabricText).fontSize!);
            }

            if (o.name === 'name') {
              (o as FabricText).set({ text: nameNum.name });
            } else if (o.name === 'num') {
              (o as FabricText).set({ text: String(nameNum.num) });
            }
          }
        });
        designEditor.render();
        await new Promise((resolve) => setTimeout(resolve, 100));
        for (let side of [
          'front',
          'back',
          'left_front',
          'right_front',
          'left_back',
          'right_back',
        ]) {
          if (side !== this.activeComponent && this.design_data.designData[side]) {
            const fabricData = this.design_data.designData[side];
            if (fabricData) {
              fabricData.objects.map((o: any) => {
                if (o.name === 'name') {
                  o.text = nameNum.name;
                } else if (o.name === 'num') {
                  o.text = String(nameNum.num);
                }
                if (['name', 'num'].includes(o.name)) {
                  const text = new FabricText();
                  text.set(o);
                  const w = text.getScaledWidth();
                  const h = text.getScaledHeight();
                  const scale = Math.min(o.originWidth / w, o.originHeight / h);
                  text.fontSize! *= scale;
                  Object.assign(o, text.toJSON());
                }
              });
              await textureManager.updataTextByFabricJSON(side, fabricData);
              this.updataTime();
            }
          }
        }
      }
    },

    //名字号码列表
    nameNumList: [] as Array<NameNum>,
    setNameNumList(nameNumList: Array<NameNum>) {
      this.nameNumList = nameNumList;
    },
    addNameNum() {
      const { goodsData } = editorStore;
      if (goodsData) {
        const sizePrice = toJS(goodsData.sizePrice) || [];
        const size = get(sizePrice, [0, 'size']);
        this.nameNumList = [...this.nameNumList, { name: '名字', num: '00', size }];
      }
    },
    delNameNum(i: number) {
      this.nameNumList.splice(i, 1);
      this.nameNumList = [...this.nameNumList];
    },
    updataNameNum(i: number, p: Partial<NameNum>) {
      this.nameNumList.map((nameNum, ii) => {
        if (ii === i) {
          Object.assign(nameNum, p);
        }
      });
      this.nameNumList = [...this.nameNumList];
    },

    //编辑名字号码
    editorNameNum: false,
    setEditorNameNum(editorNameNum: boolean) {
      this.editorNameNum = editorNameNum;
    },

    //保存
    async save(id: string = '') {
      this.setSaveIng(true);
      const { goodsData } = editorStore;

      const allThumbFiles = await preview2DRenderer.getAllthumbFile();
      // 满版印就把3d模型存为缩率图
      if (goodsData!.fillType === 0) {
        const fontFile = await thumb3DRenderer.getThumbFile();
        const backFile = await thumb3DRenderer.getBackThumbFile();
        const [fontUrl, backUrl, ...previewThumb] = await Promise.all([
          utilsServer.uploadOss(fontFile),
          utilsServer.uploadOss(backFile),
          ...allThumbFiles.map((file) => {
            return utilsServer.uploadOss(file);
          }),
        ]);
        this.design_data.thumbs = [fontUrl, backUrl];
        this.design_data.previewThumb = previewThumb;
        // 局部印就把上身效果存为缩率图
      } else if (goodsData!.fillType === 1) {
        const [fontUrl, backUrl, ...previewThumb] = await Promise.all([
          ...allThumbFiles.map((file) => {
            return utilsServer.uploadOss(file);
          }),
        ]);
        this.design_data.thumbs = [fontUrl, backUrl];
        this.design_data.previewThumb = [fontUrl, backUrl, ...previewThumb];
      }

      const hasFront =
        (get(this, ['design_data', 'designData', 'front', 'objects', 'length']) || 0) > 0;
      const hasBack =
        (get(this, ['design_data', 'designData', 'back', 'objects', 'length']) || 0) > 0;
      if (hasFront && hasBack) {
        this.design_data.printArea = 'double';
      } else if (!hasFront && hasBack) {
        this.design_data.printArea = 'back';
      } else {
        this.design_data.printArea = 'front';
      }
      try {
        const result = await userDesignService.saveProduct(this.design_data);
        id = result.id;
      } catch (error) { }
      designDataHistory.clearRedo();
      this.setSaveIng(false);
      return id;
    },
  },
  {},
  { deep: false },
));

export default editorStore;
